import asyncore
import _thread
import time
import collections

def getNextPosition(ss, i):
    while i<len(ss):
        if ss[i]==0xAA and ss[i+1]==0xAA and ss[i+2]==0xF1:
            return i
        i += 1

def parse(data):
    start = 0
    packageLen = 38
    ret = []
    while True:
        start = getNextPosition(data, start)
        if start is None or start + packageLen > len(data): break
        channels = [int.from_bytes(data[i:i+4], 'big', signed=True) for i in range(start+4, start+36, 4)]
        ret.append(channels)
        start += packageLen
    return ret
    

class Handler(asyncore.dispatcher_with_send):
    def __init__(self):
        super().__init__()
        self.dq = collections.deque()

    def handle_read(self):
        data = self.recv(8192)
        for channel in parse(data):
            self.dq.append(channel)

    def __next__(self):
        if self.dq.count() == 0 and self.connected:
            raise StopIteration
        return self.dq.popleft()

class Server(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        self.handler = Handler(sock)

class SocketStream:
    def __init__(self, host = "0.0.0.0", port = 8080) -> None:
        self.server = Server(host, port)
        _thread.start_new_thread(asyncore.loop, ())

    def __iter__(self):
        return self.server.handler